iT邦幫忙

2024 iThome 鐵人賽

DAY 3
0
Software Development

輕鬆學習設計模式Design Pattern系列 第 3

Day 3 觀察者模式 Observer Pattern

  • 分享至 

  • xImage
  •  

今天你訂閱了一個喜歡的 YouTube 頻道,這個頻道一旦有新影片發布,你就會收到通知。不需要你反覆檢查頻道是否有新內容,所有更新自動發送到你手上。在軟體開發中,我們常常需要處理這樣的情境,當一個物件的狀態發生變化時,其他相關物件需要自動更新,並做出相應的回應。這種情境下我們就可以運用觀察者模式 Observer Pattern。

什麼是觀察者模式?

觀察者模式是一種行為設計模式,它定義了一種一對多的依賴關係,當一個物件(被觀察者)發生改變時,所有依賴它的物件(觀察者)都會自動收到通知並更新自己。這讓系統中的物件之間能夠鬆散耦合,保持靈活性和可維護性。

觀察者模式在 YouTube 訂閱的應用

在這個範例中,我們將 YouTube 頻道視為「被觀察者」,訂閱該頻道的使用者則是「觀察者」。當頻道有新影片上傳時,所有訂閱者都會自動收到通知。讓我們用 C++ 來實踐這個概念。

我們定義一個 Observer 介面,所有的觀察者(訂閱者)都要實作這個介面。

class Observer {
public:
    virtual void update(const std::string& videoTitle) = 0;
    virtual ~Observer() = default;
};

接著我們定義一個 Subject 介面,讓被觀察者(YouTube 頻道)管理觀察者的訂閱和通知。

class Subject {
public:
    virtual void addObserver(std::shared_ptr<Observer> observer) = 0;
    virtual void removeObserver(std::shared_ptr<Observer> observer) = 0;
    virtual void notifyObservers() = 0;
    virtual ~Subject() = default;
};

接下來我們實作一個具體的 YouTubeChannel 類別,這個類別代表 YouTube 頻道,當有新影片發布時,它會通知所有的訂閱者。

class YouTubeChannel : public Subject {
private:
    std::list<std::shared_ptr<Observer>> subscribers;
    std::string latestVideo;

public:
    void addObserver(std::shared_ptr<Observer> observer) override {
        subscribers.push_back(observer);
    }

    void removeObserver(std::shared_ptr<Observer> observer) override {
        subscribers.remove(observer);
    }

    void notifyObservers() override {
        for (const auto& observer : subscribers) {
            observer->update(latestVideo);
        }
    }

    void uploadNewVideo(const std::string& videoTitle) {
        latestVideo = videoTitle;
        notifyObservers();
    }
};

最後我們可以定義多個觀察者來代表不同的訂閱者,他們會在接收到新影片通知時,顯示影片的標題。

class Subscriber : public Observer {
private:
    std::string name;

public:
    Subscriber(const std::string& name) : name(name) {}

    void update(const std::string& videoTitle) override {
        std::cout << name << " received notification: " 
            << videoTitle << std::endl;
    }
};

當我們將 Subscriber 加入 YouTubeChannel 的訂閱者清單時,頻道一旦上傳新影片,所有的訂閱者都會自動收到通知。

int main() {
    YouTubeChannel channel;

    std::shared_ptr<Subscriber> alice = std::make_shared<Subscriber>("Alice");
    std::shared_ptr<Subscriber> bob = std::make_shared<Subscriber>("Bob");

    channel.addObserver(alice);
    channel.addObserver(bob);
    channel.uploadNewVideo("First Video");

    channel.removeObserver(bob);
    channel.uploadNewVideo("Second Video");

    return 0;
}

執行上述程式碼,我們會得到以下輸出:

Alice received notification: First Video
Bob received notification: First Video
Alice received notification: Second Video

這個範例中使用了觀察者模式來模擬 YouTube 訂閱系統。當 YouTube 頻道上傳新影片時,所有的訂閱者都會自動收到通知。這讓我們的系統能夠更靈活地應對訂閱和通知的需求。

觀察者模式的優點

以這個例子來說,使用觀察者模式降低了耦合度,訂閱者和 YouTube 頻道之間的關係是鬆散的,YouTube 頻道不需要知道實際上是誰訂閱了它,它只需要通知所有訂閱者,這讓系統更容易擴展跟維護。

同時也具備擴展性,你可以輕鬆地新增或移除訂閱者,而不需要修改 YouTube 頻道的程式碼。

總結

觀察者模式是一種常見的設計模式,能有效處理多個物件之間的通知和更新需求。在我們生活中無所不在,例如:股票價格變化時,關注該股票的投資者都會收到通知,天氣變化時,訂閱天氣服務的使用者都會收到更新,電子報發布時,訂閱的讀者也會收到信件。下次你在設計系統時,如果遇到一對多的依賴關係,並且希望它們能夠自動更新的情況,不妨試試觀察者模式!

更多C++語言相關的文章,歡迎追蹤我的部落格
https://shengyu7697.github.io/cpp-observer-pattern/


上一篇
Day 2 策略模式 Strategy Pattern
下一篇
Day 4 裝飾者模式 Decorator Pattern
系列文
輕鬆學習設計模式Design Pattern30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言